library(tidyverse)
── Attaching core tidyverse packages ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.1     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.1     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.1     ── Conflicts ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(here)
here() starts at C:/Users/CodeClan/Desktop/CodeClan/dirty_data_project_Cailean/Task 4
library(janitor)

Attaching package: ‘janitor’

The following objects are masked from ‘package:stats’:

    chisq.test, fisher.test
#install.packages("openxlsx")
library(openxlsx)

Initial look at the data

steps: remove unneccesary data (i.e anything not given a Joy, Despair, Meh score or specifically asked for in question) - for 2015, regex to get anything wrapped in “[]” - for 2016, ^ - for 2017, regex Q6 | “1$”

# This section shows my adventure in trying to work out why what i thought would be the same regex pattern produced different results

# only_candy_2015 <- raw_candy_2015 %>% 
#   select(matches("^[[[:print:]]+]$"))
# 
# whats_the_difference <- raw_candy_2015 %>% 
#   select(matches("^[[][[:print:]]+[]]$"))
# 
# whats_the_difference2 <- raw_candy_2015 %>% 
#   select(matches("^[[]{2}[[:print:]]+[]]{1}$"))
# 
# list_a <- names(only_candy_2015) 
# list_b <- names(whats_the_difference)
# 
# list_a[!(list_a %in% list_b)]

2015 DATA

Separate candy data to reattach to relevant columns later

Using regex to select all columns that have text wrapped by square brackets, as these contain all the “candy” data

only_candy_2015 <- raw_candy_2015 %>% 
   select(matches("^[[]{1}[[:print:]]+[]]{1}$"))
clean_names_candy_2015 <- janitor::clean_names(only_candy_2015)

Separate age and trick or treating columns

also cleaning up the names adding year, gender and country columns for joining to other data sets Assigning year = 2015, gender = NA, country = NA

only_personal_data_2015 <- raw_candy_2015 %>% 
  select(`How old are you?`, `Are you going actually going trick or treating yourself?`) %>% 
  rename("age" = "How old are you?", "going_trick_or_treating" = "Are you going actually going trick or treating yourself?") %>% 
  mutate(year = 2015, .before = "age") %>% 
  mutate(gender = NA, .after = "age") %>% 
  mutate(country = NA, .after = "gender")
  

# only_personal_data_2015 %>% 
#   mutate(trick_or_treating_logical = case_when(
#     going_trick_or_treating == "No" ~ FALSE,
#     going_trick_or_treating == "Yes" ~ TRUE
#     
#   ))

rejoining data back together

rejoined_2015 <- bind_cols(only_personal_data_2015, clean_names_candy_2015)

2016 DATA

Separate candy data to reattach to relevant columns later

Similar/same process to 2015

only_candy_2016 <- raw_candy_2016 %>% 
   select(matches("^[[]{1}[[:print:]]+[]]{1}$"))

clean_names_candy_2016 <- janitor::clean_names(only_candy_2016)

# Comparing column names 

# list_a <- names(clean_names_candy_2015)
# list_b <- names(clean_names_candy_2016)
# 
# tibble(list_a[!(list_a %in% list_b)])
# tibble(list_b[!(list_b %in% list_a)])
# This converts changes the country column to a less stupid name and standardises the data 
# This will not pick up every single variant - However, it picks up most of them
country_tidied_2016 <- raw_candy_2016 %>% 
  select(`Which country do you live in?`) %>% 
  mutate(`Which country do you live in?` = tolower(`Which country do you live in?`)) %>% 
  rename(country = `Which country do you live in?`) %>% 
  mutate(country = case_when(
    country == NA  ~ "Other",
    str_detect(country, "^us|america|states$") ~ "USA",
    str_extract(country, "[u]{1}[s]{1}|[eu]+rica|trump") == TRUE ~ "USA",
    str_detect(country, "kingdom$|^uk|england|scotland|britain") ~ "UK",
    str_detect(country, "canada") ~ "Canada",
    TRUE ~ "Other"
  ))
# extract relevant personal data so it can be tidied and reconnected
only_personal_data_2016 <- raw_candy_2016 %>% 
  select(`How old are you?`, `Your gender:`,`Are you going actually going trick or treating yourself?` ) %>% 
  rename("age" = "How old are you?", 
         "going_trick_or_treating" = "Are you going actually going trick or treating yourself?",
         "gender" = "Your gender:") %>% 
  mutate(year = 2016, .before = "age")
         

Reconnecting 2016 data

rejoined_2016 <- bind_cols(only_personal_data_2016, country_tidied_2016) %>% 
  bind_cols(clean_names_candy_2016)
# ## Testing reading country using regex
# raw_candy_2016 %>% 
#   select(`Which country do you live in?`) %>% 
#   mutate(`Which country do you live in?` = tolower(`Which country do you live in?`)) %>% 
#   rename(country = `Which country do you live in?`) %>% 
#   mutate(country = case_when(
#     country == NA  ~ "Other",
#     str_detect(country, "^us|america|states$|trump") ~ "USA",
#     str_extract(country, "[u]{1}[s]{1}|america") == TRUE ~ "USA",
#     str_detect(country, "kingdom$|^uk|england|scotland") ~ "UK",
#     str_detect(country, "canada") ~ "Canada",
#     TRUE ~ "Other"
#   ))
# 
# country_tidied_2016

2017 DATA

Separate candy data to reattach to relevant columns later

This is essentially the same process as 2015 and 2016, but with a different pattern

only_candy_2017 <- raw_candy_2017 %>%
  select(matches("^Q6"))
#This pulls out all the "candy" data (assuming of course that all the relevant data is under Q6) - But they have "Q6 | " in the column names 
# This removes the "Q6 | " from all the columns  
colnames(only_candy_2017) <- gsub("Q6 [\\|] ", " ",colnames(only_candy_2017))
# Clean candy names
clean_names_candy_2017 <- janitor::clean_names(only_candy_2017) 

# comparing column names 
# 
# list_a <- names(clean_names_candy_2015)
# list_b <- names(clean_names_candy_2017)
# 
# tibble(list_a[!(list_a %in% list_b)])
# tibble(list_b[!(list_b %in% list_a)])

remove personal data

Like with 2016, country has been left at this stage to be cleaned separately

only_personal_data_2017 <- raw_candy_2017 %>% 
  select(`Q3: AGE`, `Q2: GENDER`, `Q1: GOING OUT?`) %>% 
  rename("age" = "Q3: AGE", 
         "going_trick_or_treating" = "Q1: GOING OUT?",
         "gender" = "Q2: GENDER") %>% 
  mutate(year = 2017, .before = "age")

cleaning the country data - as before, converting to lower case, then using regex patterns to standardise naming

country_tidied_2017 <- raw_candy_2017 %>% 
  select(`Q4: COUNTRY`) %>% 
  mutate(`Q4: COUNTRY` = tolower(`Q4: COUNTRY`)) %>% 
  rename(country = `Q4: COUNTRY`) %>% 
  mutate(country = case_when(
    country == NA  ~ "Other",
    str_detect(country, "^us|america|states$") ~ "USA",
    str_extract(country, "[u]{1}[s]{1}|[eu]+rica|trump") == TRUE ~ "USA",
    str_detect(country, "kingdom$|^uk|england|scotland|britain") ~ "UK",
    str_detect(country, "canada") ~ "Canada",
    TRUE ~ "Other"
  ))

rejoining 2017 data

rejoined_2017 <- bind_cols(only_personal_data_2017, country_tidied_2017) %>% 
  bind_cols(clean_names_candy_2017)

rejoining the datasets and final cleaning

rejoined_candy <- full_join(rejoined_2015, rejoined_2016) %>%
  full_join(rejoined_2017)
Joining with `by = join_by(year, age, gender, country, going_trick_or_treating, butterfinger, x100_grand_bar, anonymous_brown_globs_that_come_in_black_and_orange_wrappers, any_full_sized_candy_bar, black_jacks, bottle_caps, cadbury_creme_eggs, candy_corn, vials_of_pure_high_fructose_corn_syrup_for_main_lining_into_your_vein, candy_that_is_clearly_just_the_stuff_given_out_for_free_at_restaurants, cash_or_other_forms_of_legal_tender, chiclets, caramellos, snickers, dental_paraphenalia, dots, fuzzy_peaches, generic_brand_acetaminophen, glow_sticks, broken_glow_stick, goo_goo_clusters, good_n_plenty, gum_from_baseball_cards, gummy_bears_straight_up, creepy_religious_comics_chick_tracts, healthy_fruit, heath_bar, hershey_s_milk_chocolate, hugs_actual_physical_hugs, jolly_rancher_bad_flavor, jolly_ranchers_good_flavor, kale_smoothie, kinder_happy_hippo, kit_kat, hard_candy, lemon_heads, licorice_not_black, lindt_truffle, lollipops, mars, mary_janes, maynards, milk_duds, laffy_taffy, minibags_of_chips, joy_joy_mit_iodine, reggie_jackson_bar, pixy_stix, nerds, nestle_crunch, nown_laters, pencils, milky_way, reese_s_peanut_butter_cups, tolberone_something_or_other, junior_mints, senior_mints, mint_kisses, mint_juleps, peanut_m_m_s, regular_m_ms, rolos, skittles, smarties_american, smarties_commonwealth, chick_o_sticks_we_don_t_know_what_that_is, spotted_dick, starburst, swedish_fish, those_odd_marshmallow_circus_peanut_things, three_musketeers, trail_mix, twix, vicodin, white_bread, whole_wheat_anything, york_peppermint_patties, necco_wafers)`Joining with `by = join_by(year, age, gender, country, going_trick_or_treating, butterfinger, x100_grand_bar, any_full_sized_candy_bar, black_jacks, bottle_caps, cadbury_creme_eggs, candy_corn, vials_of_pure_high_fructose_corn_syrup_for_main_lining_into_your_vein, candy_that_is_clearly_just_the_stuff_given_out_for_free_at_restaurants, cash_or_other_forms_of_legal_tender, chiclets, caramellos, snickers, dental_paraphenalia, dots, fuzzy_peaches, generic_brand_acetaminophen, glow_sticks, broken_glow_stick, goo_goo_clusters, good_n_plenty, gum_from_baseball_cards, gummy_bears_straight_up, creepy_religious_comics_chick_tracts, healthy_fruit, heath_bar, hershey_s_milk_chocolate, hugs_actual_physical_hugs, jolly_rancher_bad_flavor, jolly_ranchers_good_flavor, kale_smoothie, kinder_happy_hippo, kit_kat, hard_candy, lemon_heads, licorice_not_black, lindt_truffle, lollipops, mars, maynards, milk_duds, laffy_taffy, minibags_of_chips, joy_joy_mit_iodine, reggie_jackson_bar, pixy_stix, nerds, nestle_crunch, nown_laters, pencils, milky_way, reese_s_peanut_butter_cups, tolberone_something_or_other, junior_mints, senior_mints, mint_kisses, mint_juleps, peanut_m_m_s, regular_m_ms, rolos, skittles, smarties_american, smarties_commonwealth, chick_o_sticks_we_don_t_know_what_that_is, spotted_dick, starburst, swedish_fish, those_odd_marshmallow_circus_peanut_things, three_musketeers, trail_mix, twix, vicodin, white_bread, whole_wheat_anything, york_peppermint_patties, necco_wafers, bonkers_the_candy, bonkers_the_board_game, boxo_raisins, chardonnay, coffee_crisp, dove_bars, hersheys_dark_chocolate, hersheys_kisses, licorice_yes_black, mike_and_ike, blue_m_ms, red_m_ms, mr_goodbar, peeps, reeses_pieces, sourpatch_kids_i_e_abominations_of_nature, sweet_tarts, sweetums_a_friend_to_diabetes, tic_tacs, whatchamacallit_bars)`
# check to see how many NA's were present in age before mutating to integer (317)
# rejoined_candy %>% 
#   select(age) %>% 
#   filter(is.na(age)) %>% 
#   count()
# changing the age column to integer - this will eliminate any "non-number" answers (i.e. "enough" "fifty-four") and replace them with NA 
# I have decided to leave the NA's in the data
# Logically, age cannot be over a certain value - I've decided to replace anything over 100 with NA
rejoined_candy <- rejoined_candy %>% 
  mutate(age = as.integer(age)) %>% 
  mutate(age = case_when(
    age > 100 ~ NA,
    age <= 100 ~ age
  ))
Warning: There were 2 warnings in `mutate()`.
The first warning was:
ℹ In argument: `age = as.integer(age)`.
Caused by warning:
! NAs introduced by coercion
ℹ Run ]8;;ide:run:dplyr::last_dplyr_warnings()dplyr::last_dplyr_warnings()]8;; to see the 1 remaining warning.
# rejoined_candy %>%
#   filter(is.na(age)) %>%
#   count()
#checking gender column
unique(rejoined_candy$gender)
[1] NA                   "Male"               "Female"             "Other"              "I'd rather not say"
# counting NA's to check next step has worked
# rejoined_candy %>%
#   select(gender) %>%
#   filter(is.na(gender)) %>%
#   count()


# replacing NA's with "Not Provided" 
rejoined_candy <- rejoined_candy %>% 
  mutate(gender = replace_na(gender, "Not Provided"))

# doing the same for country - This is technically not necessary, but i think makes it clearer why 2015 has no country data
rejoined_candy <- rejoined_candy %>% 
  mutate(country = replace_na(country, "Not Provided in 2015 data"))

Writing cleaned data


  1. \[][[:alnum:]]+[\]↩︎

LS0tDQp0aXRsZTogIlRhc2sgNCAtIEhhbGxvd2VlbiBDYW5keSBEYXRhIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoaGVyZSkNCmxpYnJhcnkoamFuaXRvcikNCiNpbnN0YWxsLnBhY2thZ2VzKCJvcGVueGxzeCIpDQpsaWJyYXJ5KG9wZW54bHN4KQ0KYGBgDQoNCkluaXRpYWwgbG9vayBhdCB0aGUgZGF0YQ0KDQpgYGB7cn0NCnJhd19jYW5keV8yMDE1IDwtIHJlYWR4bDo6cmVhZF94bHN4KGhlcmUoInJhd19kYXRhL2JvaW5nLWJvaW5nLWNhbmR5LTIwMTUueGxzeCIpKQ0KcmF3X2NhbmR5XzIwMTYgPC0gcmVhZHhsOjpyZWFkX3hsc3goaGVyZSgicmF3X2RhdGEvYm9pbmctYm9pbmctY2FuZHktMjAxNi54bHN4IikpDQpyYXdfY2FuZHlfMjAxNyA8LSByZWFkeGw6OnJlYWRfeGxzeChoZXJlKCJyYXdfZGF0YS9ib2luZy1ib2luZy1jYW5keS0yMDE3Lnhsc3giKSkNCmBgYA0KDQpzdGVwczogDQogIHJlbW92ZSB1bm5lY2Nlc2FyeSBkYXRhIChpLmUgYW55dGhpbmcgbm90IGdpdmVuIGEgSm95LCBEZXNwYWlyLCBNZWggc2NvcmUgb3Igc3BlY2lmaWNhbGx5IGFza2VkIGZvciBpbiBxdWVzdGlvbikNCiAgICAgLSBmb3IgMjAxNSwgcmVnZXggdG8gZ2V0IGFueXRoaW5nIHdyYXBwZWQgaW4gIltdIiANCiAgICAgLSBmb3IgMjAxNiwgXg0KICAgICAtIGZvciAyMDE3LCByZWdleCBRNiB8IA0KIl5bXFxbXVtbOmFsbnVtOl1dK1tcXF1dJCINCmBgYHtyfQ0KIyBUaGlzIHNlY3Rpb24gc2hvd3MgbXkgYWR2ZW50dXJlIGluIHRyeWluZyB0byB3b3JrIG91dCB3aHkgd2hhdCBpIHRob3VnaHQgd291bGQgYmUgdGhlIHNhbWUgcmVnZXggcGF0dGVybiBwcm9kdWNlZCBkaWZmZXJlbnQgcmVzdWx0cw0KDQojIG9ubHlfY2FuZHlfMjAxNSA8LSByYXdfY2FuZHlfMjAxNSAlPiUgDQojICAgc2VsZWN0KG1hdGNoZXMoIl5bW1s6cHJpbnQ6XV0rXSQiKSkNCiMgDQojIHdoYXRzX3RoZV9kaWZmZXJlbmNlIDwtIHJhd19jYW5keV8yMDE1ICU+JSANCiMgICBzZWxlY3QobWF0Y2hlcygiXltbXVtbOnByaW50Ol1dK1tdXSQiKSkNCiMgDQojIHdoYXRzX3RoZV9kaWZmZXJlbmNlMiA8LSByYXdfY2FuZHlfMjAxNSAlPiUgDQojICAgc2VsZWN0KG1hdGNoZXMoIl5bW117Mn1bWzpwcmludDpdXStbXV17MX0kIikpDQojIA0KIyBsaXN0X2EgPC0gbmFtZXMob25seV9jYW5keV8yMDE1KSANCiMgbGlzdF9iIDwtIG5hbWVzKHdoYXRzX3RoZV9kaWZmZXJlbmNlKQ0KIyANCiMgbGlzdF9hWyEobGlzdF9hICVpbiUgbGlzdF9iKV0NCmBgYA0KICAgIA0KICANCiMjIDIwMTUgREFUQQ0KDQojIFNlcGFyYXRlIGNhbmR5IGRhdGEgdG8gcmVhdHRhY2ggdG8gcmVsZXZhbnQgY29sdW1ucyBsYXRlciAgICANClVzaW5nIHJlZ2V4IHRvIHNlbGVjdCBhbGwgY29sdW1ucyB0aGF0IGhhdmUgdGV4dCB3cmFwcGVkIGJ5IHNxdWFyZSBicmFja2V0cywgYXMgdGhlc2UgY29udGFpbiBhbGwgdGhlICJjYW5keSIgZGF0YQ0KYGBge3J9DQpvbmx5X2NhbmR5XzIwMTUgPC0gcmF3X2NhbmR5XzIwMTUgJT4lIA0KICAgc2VsZWN0KG1hdGNoZXMoIl5bW117MX1bWzpwcmludDpdXStbXV17MX0kIikpDQpgYGANCg0KYGBge3J9DQpjbGVhbl9uYW1lc19jYW5keV8yMDE1IDwtIGphbml0b3I6OmNsZWFuX25hbWVzKG9ubHlfY2FuZHlfMjAxNSkNCmBgYA0KDQojIFNlcGFyYXRlIGFnZSBhbmQgdHJpY2sgb3IgdHJlYXRpbmcgY29sdW1ucyANCmFsc28gY2xlYW5pbmcgdXAgdGhlIG5hbWVzIA0KYWRkaW5nIHllYXIsIGdlbmRlciBhbmQgY291bnRyeSBjb2x1bW5zIGZvciBqb2luaW5nIHRvIG90aGVyIGRhdGEgc2V0cw0KQXNzaWduaW5nIHllYXIgPSAyMDE1LCBnZW5kZXIgPSBOQSwgY291bnRyeSA9IE5BIA0KDQpgYGB7cn0NCm9ubHlfcGVyc29uYWxfZGF0YV8yMDE1IDwtIHJhd19jYW5keV8yMDE1ICU+JSANCiAgc2VsZWN0KGBIb3cgb2xkIGFyZSB5b3U/YCwgYEFyZSB5b3UgZ29pbmcgYWN0dWFsbHkgZ29pbmcgdHJpY2sgb3IgdHJlYXRpbmcgeW91cnNlbGY/YCkgJT4lIA0KICByZW5hbWUoImFnZSIgPSAiSG93IG9sZCBhcmUgeW91PyIsICJnb2luZ190cmlja19vcl90cmVhdGluZyIgPSAiQXJlIHlvdSBnb2luZyBhY3R1YWxseSBnb2luZyB0cmljayBvciB0cmVhdGluZyB5b3Vyc2VsZj8iKSAlPiUgDQogIG11dGF0ZSh5ZWFyID0gMjAxNSwgLmJlZm9yZSA9ICJhZ2UiKSAlPiUgDQogIG11dGF0ZShnZW5kZXIgPSBOQSwgLmFmdGVyID0gImFnZSIpICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBOQSwgLmFmdGVyID0gImdlbmRlciIpDQogIA0KYGBgDQoNCnJlam9pbmluZyBkYXRhIGJhY2sgdG9nZXRoZXINCg0KYGBge3J9DQpyZWpvaW5lZF8yMDE1IDwtIGJpbmRfY29scyhvbmx5X3BlcnNvbmFsX2RhdGFfMjAxNSwgY2xlYW5fbmFtZXNfY2FuZHlfMjAxNSkNCg0KYGBgDQoNCiMjIDIwMTYgREFUQQ0KDQojIFNlcGFyYXRlIGNhbmR5IGRhdGEgdG8gcmVhdHRhY2ggdG8gcmVsZXZhbnQgY29sdW1ucyBsYXRlciAgDQojIFNpbWlsYXIvc2FtZSBwcm9jZXNzIHRvIDIwMTUNCg0KYGBge3J9DQpvbmx5X2NhbmR5XzIwMTYgPC0gcmF3X2NhbmR5XzIwMTYgJT4lIA0KICAgc2VsZWN0KG1hdGNoZXMoIl5bW117MX1bWzpwcmludDpdXStbXV17MX0kIikpDQoNCmNsZWFuX25hbWVzX2NhbmR5XzIwMTYgPC0gamFuaXRvcjo6Y2xlYW5fbmFtZXMob25seV9jYW5keV8yMDE2KQ0KDQojIENvbXBhcmluZyBjb2x1bW4gbmFtZXMgDQojIEFzc3VtaW5nIHdlIHdhbnRlZCBhIG1vcmUgY29tcGxldGUgYW5hbHlzaXMsIHdlIGNvdWxkIHVzZSB0aGlzIGNvbXBhcmlzb24gdG8gY2hlY2sgaWYgdGhlcmUgd2VyZSBhbnkgc2xpZ2h0IG5hbWUgY2hhbmdlcyANCiMgZS5nIEJ1dHRlcmZpbmdlciBpbiAyMDE1IC0+IEJ1dHRlcmZpbmdlcnMgaW4gMjAxNg0KIyBEdWUgdG8gdGltZSwgSSd2ZSBjaG9zZW4gbm90IHRvIGRvIHRoaXMsIGV2ZW4gdGhvdWdoIGl0IGNvdWxkIGFmZmVjdCByZXN1bHRzDQoNCiMgbGlzdF9hIDwtIG5hbWVzKGNsZWFuX25hbWVzX2NhbmR5XzIwMTUpDQojIGxpc3RfYiA8LSBuYW1lcyhjbGVhbl9uYW1lc19jYW5keV8yMDE2KQ0KIyANCiMgdGliYmxlKGxpc3RfYVshKGxpc3RfYSAlaW4lIGxpc3RfYildKQ0KIyB0aWJibGUobGlzdF9iWyEobGlzdF9iICVpbiUgbGlzdF9hKV0pDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBUaGlzIGNvbnZlcnRzIGNoYW5nZXMgdGhlIGNvdW50cnkgY29sdW1uIHRvIGEgbGVzcyBzdHVwaWQgbmFtZSBhbmQgc3RhbmRhcmRpc2VzIG5hbWVzDQojIFRoaXMgd2lsbCBub3QgcGljayB1cCBldmVyeSBzaW5nbGUgdmFyaWFudCAtIEhvd2V2ZXIsIGl0IHBpY2tzIHVwIG1vc3Qgb2YgdGhlbQ0KDQpjb3VudHJ5X3RpZGllZF8yMDE2IDwtIHJhd19jYW5keV8yMDE2ICU+JSANCiAgc2VsZWN0KGBXaGljaCBjb3VudHJ5IGRvIHlvdSBsaXZlIGluP2ApICU+JSANCiAgbXV0YXRlKGBXaGljaCBjb3VudHJ5IGRvIHlvdSBsaXZlIGluP2AgPSB0b2xvd2VyKGBXaGljaCBjb3VudHJ5IGRvIHlvdSBsaXZlIGluP2ApKSAlPiUgDQogIHJlbmFtZShjb3VudHJ5ID0gYFdoaWNoIGNvdW50cnkgZG8geW91IGxpdmUgaW4/YCkgJT4lIA0KICBtdXRhdGUoY291bnRyeSA9IGNhc2Vfd2hlbigNCiAgICBjb3VudHJ5ID09IE5BICB+ICJPdGhlciIsDQogICAgc3RyX2RldGVjdChjb3VudHJ5LCAiXnVzfGFtZXJpY2F8c3RhdGVzJCIpIH4gIlVTQSIsDQogICAgc3RyX2V4dHJhY3QoY291bnRyeSwgIlt1XXsxfVtzXXsxfXxbZXVdK3JpY2F8dHJ1bXAiKSA9PSBUUlVFIH4gIlVTQSIsDQogICAgc3RyX2RldGVjdChjb3VudHJ5LCAia2luZ2RvbSR8XnVrfGVuZ2xhbmR8c2NvdGxhbmR8YnJpdGFpbiIpIH4gIlVLIiwNCiAgICBzdHJfZGV0ZWN0KGNvdW50cnksICJjYW5hZGEiKSB+ICJDYW5hZGEiLA0KICAgIFRSVUUgfiAiT3RoZXIiDQogICkpDQpgYGANCg0KYGBge3J9DQojIGV4dHJhY3QgcmVsZXZhbnQgcGVyc29uYWwgZGF0YSBzbyBpdCBjYW4gYmUgdGlkaWVkIGFuZCByZWNvbm5lY3RlZA0Kb25seV9wZXJzb25hbF9kYXRhXzIwMTYgPC0gcmF3X2NhbmR5XzIwMTYgJT4lIA0KICBzZWxlY3QoYEhvdyBvbGQgYXJlIHlvdT9gLCBgWW91ciBnZW5kZXI6YCxgQXJlIHlvdSBnb2luZyBhY3R1YWxseSBnb2luZyB0cmljayBvciB0cmVhdGluZyB5b3Vyc2VsZj9gICkgJT4lIA0KICByZW5hbWUoImFnZSIgPSAiSG93IG9sZCBhcmUgeW91PyIsIA0KICAgICAgICAgImdvaW5nX3RyaWNrX29yX3RyZWF0aW5nIiA9ICJBcmUgeW91IGdvaW5nIGFjdHVhbGx5IGdvaW5nIHRyaWNrIG9yIHRyZWF0aW5nIHlvdXJzZWxmPyIsDQogICAgICAgICAiZ2VuZGVyIiA9ICJZb3VyIGdlbmRlcjoiKSAlPiUgDQogIG11dGF0ZSh5ZWFyID0gMjAxNiwgLmJlZm9yZSA9ICJhZ2UiKQ0KICAgICAgICAgDQpgYGANCg0KIyBSZWNvbm5lY3RpbmcgMjAxNiBkYXRhDQoNCmBgYHtyfQ0KcmVqb2luZWRfMjAxNiA8LSBiaW5kX2NvbHMob25seV9wZXJzb25hbF9kYXRhXzIwMTYsIGNvdW50cnlfdGlkaWVkXzIwMTYpICU+JSANCiAgYmluZF9jb2xzKGNsZWFuX25hbWVzX2NhbmR5XzIwMTYpDQpgYGANCg0KDQpgYGB7cn0NCiMgIyMgVGVzdGluZyByZWFkaW5nIGNvdW50cnkgdXNpbmcgcmVnZXgNCiMgcmF3X2NhbmR5XzIwMTYgJT4lIA0KIyAgIHNlbGVjdChgV2hpY2ggY291bnRyeSBkbyB5b3UgbGl2ZSBpbj9gKSAlPiUgDQojICAgbXV0YXRlKGBXaGljaCBjb3VudHJ5IGRvIHlvdSBsaXZlIGluP2AgPSB0b2xvd2VyKGBXaGljaCBjb3VudHJ5IGRvIHlvdSBsaXZlIGluP2ApKSAlPiUgDQojICAgcmVuYW1lKGNvdW50cnkgPSBgV2hpY2ggY291bnRyeSBkbyB5b3UgbGl2ZSBpbj9gKSAlPiUgDQojICAgbXV0YXRlKGNvdW50cnkgPSBjYXNlX3doZW4oDQojICAgICBjb3VudHJ5ID09IE5BICB+ICJPdGhlciIsDQojICAgICBzdHJfZGV0ZWN0KGNvdW50cnksICJedXN8YW1lcmljYXxzdGF0ZXMkfHRydW1wIikgfiAiVVNBIiwNCiMgICAgIHN0cl9leHRyYWN0KGNvdW50cnksICJbdV17MX1bc117MX18YW1lcmljYSIpID09IFRSVUUgfiAiVVNBIiwNCiMgICAgIHN0cl9kZXRlY3QoY291bnRyeSwgImtpbmdkb20kfF51a3xlbmdsYW5kfHNjb3RsYW5kIikgfiAiVUsiLA0KIyAgICAgc3RyX2RldGVjdChjb3VudHJ5LCAiY2FuYWRhIikgfiAiQ2FuYWRhIiwNCiMgICAgIFRSVUUgfiAiT3RoZXIiDQojICAgKSkNCiMgDQojIGNvdW50cnlfdGlkaWVkXzIwMTYNCmBgYA0KDQoNCg0KDQojIyAyMDE3IERBVEENCg0KIyBTZXBhcmF0ZSBjYW5keSBkYXRhIHRvIHJlYXR0YWNoIHRvIHJlbGV2YW50IGNvbHVtbnMgbGF0ZXIgIA0KVGhpcyBpcyBlc3NlbnRpYWxseSB0aGUgc2FtZSBwcm9jZXNzIGFzIDIwMTUgYW5kIDIwMTYsIGJ1dCB3aXRoIGEgZGlmZmVyZW50IHBhdHRlcm4NCg0KYGBge3J9DQpvbmx5X2NhbmR5XzIwMTcgPC0gcmF3X2NhbmR5XzIwMTcgJT4lDQogIHNlbGVjdChtYXRjaGVzKCJeUTYiKSkNCiNUaGlzIHB1bGxzIG91dCBhbGwgdGhlICJjYW5keSIgZGF0YSAoYXNzdW1pbmcgb2YgY291cnNlIHRoYXQgYWxsIHRoZSByZWxldmFudCBkYXRhIGlzIHVuZGVyIFE2KSAtIEJ1dCB0aGV5IGhhdmUgIlE2IHwgIiBpbiB0aGUgY29sdW1uIG5hbWVzIA0KYGBgDQoNCmBgYHtyfQ0KIyBUaGlzIHJlbW92ZXMgdGhlICJRNiB8ICIgZnJvbSBhbGwgdGhlIGNvbHVtbnMgIA0KY29sbmFtZXMob25seV9jYW5keV8yMDE3KSA8LSBnc3ViKCJRNiBbXFx8XSAiLCAiICIsY29sbmFtZXMob25seV9jYW5keV8yMDE3KSkNCmBgYA0KDQpgYGB7cn0NCiMgQ2xlYW4gY2FuZHkgbmFtZXMNCmNsZWFuX25hbWVzX2NhbmR5XzIwMTcgPC0gamFuaXRvcjo6Y2xlYW5fbmFtZXMob25seV9jYW5keV8yMDE3KSANCg0KIyBjb21wYXJpbmcgY29sdW1uIG5hbWVzIA0KIyANCiMgbGlzdF9hIDwtIG5hbWVzKGNsZWFuX25hbWVzX2NhbmR5XzIwMTUpDQojIGxpc3RfYiA8LSBuYW1lcyhjbGVhbl9uYW1lc19jYW5keV8yMDE3KQ0KIyANCiMgdGliYmxlKGxpc3RfYVshKGxpc3RfYSAlaW4lIGxpc3RfYildKQ0KIyB0aWJibGUobGlzdF9iWyEobGlzdF9iICVpbiUgbGlzdF9hKV0pDQpgYGANCg0KDQojIHJlbW92ZSBwZXJzb25hbCBkYXRhIA0KTGlrZSB3aXRoIDIwMTYsIGNvdW50cnkgaGFzIGJlZW4gbGVmdCBhdCB0aGlzIHN0YWdlIHRvIGJlIGNsZWFuZWQgc2VwYXJhdGVseQ0KYGBge3J9DQpvbmx5X3BlcnNvbmFsX2RhdGFfMjAxNyA8LSByYXdfY2FuZHlfMjAxNyAlPiUgDQogIHNlbGVjdChgUTM6IEFHRWAsIGBRMjogR0VOREVSYCwgYFExOiBHT0lORyBPVVQ/YCkgJT4lIA0KICByZW5hbWUoImFnZSIgPSAiUTM6IEFHRSIsIA0KICAgICAgICAgImdvaW5nX3RyaWNrX29yX3RyZWF0aW5nIiA9ICJRMTogR09JTkcgT1VUPyIsDQogICAgICAgICAiZ2VuZGVyIiA9ICJRMjogR0VOREVSIikgJT4lIA0KICBtdXRhdGUoeWVhciA9IDIwMTcsIC5iZWZvcmUgPSAiYWdlIikNCmBgYA0KDQojIGNsZWFuaW5nIHRoZSBjb3VudHJ5IGRhdGEgLSBhcyBiZWZvcmUsIGNvbnZlcnRpbmcgdG8gbG93ZXIgY2FzZSwgdGhlbiB1c2luZyByZWdleCBwYXR0ZXJucyB0byBzdGFuZGFyZGlzZSBuYW1pbmcNCmBgYHtyfQ0KY291bnRyeV90aWRpZWRfMjAxNyA8LSByYXdfY2FuZHlfMjAxNyAlPiUgDQogIHNlbGVjdChgUTQ6IENPVU5UUllgKSAlPiUgDQogIG11dGF0ZShgUTQ6IENPVU5UUllgID0gdG9sb3dlcihgUTQ6IENPVU5UUllgKSkgJT4lIA0KICByZW5hbWUoY291bnRyeSA9IGBRNDogQ09VTlRSWWApICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBjYXNlX3doZW4oDQogICAgY291bnRyeSA9PSBOQSAgfiAiT3RoZXIiLA0KICAgIHN0cl9kZXRlY3QoY291bnRyeSwgIl51c3xhbWVyaWNhfHN0YXRlcyQiKSB+ICJVU0EiLA0KICAgIHN0cl9leHRyYWN0KGNvdW50cnksICJbdV17MX1bc117MX18W2V1XStyaWNhfHRydW1wIikgPT0gVFJVRSB+ICJVU0EiLA0KICAgIHN0cl9kZXRlY3QoY291bnRyeSwgImtpbmdkb20kfF51a3xlbmdsYW5kfHNjb3RsYW5kfGJyaXRhaW4iKSB+ICJVSyIsDQogICAgc3RyX2RldGVjdChjb3VudHJ5LCAiY2FuYWRhIikgfiAiQ2FuYWRhIiwNCiAgICBUUlVFIH4gIk90aGVyIg0KICApKQ0KYGBgDQoNCiMgcmVqb2luaW5nIDIwMTcgZGF0YQ0KDQpgYGB7cn0NCnJlam9pbmVkXzIwMTcgPC0gYmluZF9jb2xzKG9ubHlfcGVyc29uYWxfZGF0YV8yMDE3LCBjb3VudHJ5X3RpZGllZF8yMDE3KSAlPiUgDQogIGJpbmRfY29scyhjbGVhbl9uYW1lc19jYW5keV8yMDE3KQ0KYGBgDQoNCiMjIHJlam9pbmluZyB0aGUgZGF0YXNldHMgYW5kIGZpbmFsIGNsZWFuaW5nDQoNCmBgYHtyfQ0KcmVqb2luZWRfY2FuZHkgPC0gZnVsbF9qb2luKHJlam9pbmVkXzIwMTUsIHJlam9pbmVkXzIwMTYpICU+JQ0KICBmdWxsX2pvaW4ocmVqb2luZWRfMjAxNykNCmBgYA0KDQpgYGB7cn0NCiMgY2hlY2sgdG8gc2VlIGhvdyBtYW55IE5BJ3Mgd2VyZSBwcmVzZW50IGluIGFnZSBiZWZvcmUgbXV0YXRpbmcgdG8gaW50ZWdlciAoMzE3KQ0KIyByZWpvaW5lZF9jYW5keSAlPiUgDQojICAgc2VsZWN0KGFnZSkgJT4lIA0KIyAgIGZpbHRlcihpcy5uYShhZ2UpKSAlPiUgDQojICAgY291bnQoKQ0KYGBgDQoNCg0KYGBge3J9DQojIGNoYW5naW5nIHRoZSBhZ2UgY29sdW1uIHRvIGludGVnZXIgLSB0aGlzIHdpbGwgZWxpbWluYXRlIGFueSAibm9uLW51bWJlciIgYW5zd2VycyAoaS5lLiAiZW5vdWdoIiAiZmlmdHktZm91ciIpIGFuZCByZXBsYWNlIHRoZW0gd2l0aCBOQSANCiMgSSBoYXZlIGRlY2lkZWQgdG8gbGVhdmUgdGhlIE5BJ3MgaW4gdGhlIGRhdGENCiMgTG9naWNhbGx5LCBhZ2UgY2Fubm90IGJlIG92ZXIgYSBjZXJ0YWluIHZhbHVlIC0gSSd2ZSBkZWNpZGVkIHRvIHJlcGxhY2UgYW55dGhpbmcgb3ZlciAxMDAgd2l0aCBOQQ0KcmVqb2luZWRfY2FuZHkgPC0gcmVqb2luZWRfY2FuZHkgJT4lIA0KICBtdXRhdGUoYWdlID0gYXMuaW50ZWdlcihhZ2UpKSAlPiUgDQogIG11dGF0ZShhZ2UgPSBjYXNlX3doZW4oDQogICAgYWdlID4gMTAwIH4gTkEsDQogICAgYWdlIDw9IDEwMCB+IGFnZQ0KICApKQ0KDQoNCiMgcmVqb2luZWRfY2FuZHkgJT4lDQojICAgZmlsdGVyKGlzLm5hKGFnZSkpICU+JQ0KIyAgIGNvdW50KCkNCmBgYA0KDQpgYGB7cn0NCiNjaGVja2luZyBnZW5kZXIgY29sdW1uDQp1bmlxdWUocmVqb2luZWRfY2FuZHkkZ2VuZGVyKQ0KDQojIGNvdW50aW5nIE5BJ3MgdG8gY2hlY2sgbmV4dCBzdGVwIGhhcyB3b3JrZWQNCiMgcmVqb2luZWRfY2FuZHkgJT4lDQojICAgc2VsZWN0KGdlbmRlcikgJT4lDQojICAgZmlsdGVyKGlzLm5hKGdlbmRlcikpICU+JQ0KIyAgIGNvdW50KCkNCg0KDQojIHJlcGxhY2luZyBOQSdzIHdpdGggIk5vdCBQcm92aWRlZCIgDQpyZWpvaW5lZF9jYW5keSA8LSByZWpvaW5lZF9jYW5keSAlPiUgDQogIG11dGF0ZShnZW5kZXIgPSByZXBsYWNlX25hKGdlbmRlciwgIk5vdCBQcm92aWRlZCIpKQ0KDQojIGRvaW5nIHRoZSBzYW1lIGZvciBjb3VudHJ5IC0gVGhpcyBpcyB0ZWNobmljYWxseSBub3QgbmVjZXNzYXJ5LCBidXQgaSB0aGluayBtYWtlcyBpdCBjbGVhcmVyIHdoeSAyMDE1IGhhcyBubyBjb3VudHJ5IGRhdGENCnJlam9pbmVkX2NhbmR5IDwtIHJlam9pbmVkX2NhbmR5ICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSByZXBsYWNlX25hKGNvdW50cnksICJOb3QgUHJvdmlkZWQgaW4gMjAxNSBkYXRhIikpDQpgYGANCg0KDQojIFdyaXRpbmcgY2xlYW5lZCBkYXRhDQoNCmBgYHtyfQ0KY2xlYW5fY2FuZHkgPC0gcmVqb2luZWRfY2FuZHkNCg0Kd3JpdGUueGxzeChjbGVhbl9jYW5keSwgaGVyZSgiY2xlYW5fZGF0YS9jbGVhbl9jYW5keS54bHN4IikpDQpgYGANCg0K